package org.irri.smta.rest.impl;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.collections.CollectionUtils;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.irri.smta.domain.Material;
import org.irri.smta.domain.SmtaReport;
import org.irri.smta.rest.IRestfulService;
import org.irri.smta.service.IMaterialService;
import org.irri.smta.service.ISmtaReportService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

@Controller
public class SmtaReportRestfulService implements IRestfulService {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(SmtaReportRestfulService.class);
	
	@Inject
	@Named("smtaReportService")
	private ISmtaReportService<SmtaReport, Long> smtaReportService;

	@Inject
	@Named("materialService")
	private IMaterialService<Material, Long> materialService;
	
	@RequestMapping(value = "/smtareport/symbol/{symbol}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public String getSmtaReportBySymbolAsJson(@PathVariable(value = "symbol") String symbol) {
		List<SmtaReport> smtaReportList = smtaReportService.findBySymbol(symbol);
		if (CollectionUtils.isNotEmpty(smtaReportList)) {
			SmtaReport smtaReport = smtaReportList.get(0);
			return toJson(smtaReport);
		}
		return "{}";
	}
	
	@RequestMapping(value = "/smtareportlist/symbol/{symbol}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public String getSmtaReportListBySymbolAsJson(@PathVariable(value = "symbol") String symbol) {
		List<SmtaReport> smtaReportList = smtaReportService.findBySymbol(symbol);
		if (CollectionUtils.isNotEmpty(smtaReportList)) {
			return toJson(smtaReportList);
		}
		return "{}";
	}
	
	@RequestMapping(value = "/smtareport", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
	@ResponseStatus(HttpStatus.CREATED)
	@ResponseBody
	public Long addSmtaReport(@RequestBody Map<String, String> map) {
		ObjectMapper mapper = new ObjectMapper();
		String jsonString = map.get("jsonString");
		try {
			SmtaReport smtaReport = mapper.readValue(jsonString, SmtaReport.class);
			List<SmtaReport> smtaReportList = smtaReportService.findBySymbol(smtaReport.getSymbol());
			if (CollectionUtils.isNotEmpty(smtaReportList)) {
				updateSmtaReport(map);
				return 0L;
			} else {
				SmtaReport newSmtaReport = smtaReportService.create(smtaReport);
				if (newSmtaReport != null && newSmtaReport.getId() != null) {
					LOGGER.info("SMTA Report added: " + newSmtaReport);
					return newSmtaReport.getId();
				}
			}
		} catch (JsonParseException e) {
			LOGGER.error(e.getMessage());
		} catch (JsonMappingException e) {
			LOGGER.error(e.getMessage());
		} catch (IOException e) {
			LOGGER.error(e.getMessage());
		}
		return -1L;
	}

	@RequestMapping(value = "/smtareport", method = RequestMethod.PUT, consumes = "application/json")
	@ResponseStatus(HttpStatus.OK)
	public void updateSmtaReport(@RequestBody Map<String, String> map) {
		ObjectMapper mapper = new ObjectMapper();
		String jsonString = map.get("jsonString");
		try {
			SmtaReport smtaReport = mapper.readValue(jsonString,
					SmtaReport.class);
			List<SmtaReport> smtaReportList = smtaReportService.findBySymbol(smtaReport.getSymbol());
			if (CollectionUtils.isNotEmpty(smtaReportList)) {
				SmtaReport smtaReportDb = smtaReportList.get(0);
				smtaReport.setId(smtaReportDb.getId());
				SmtaReport updatedSmtaReport = smtaReportService.update(smtaReport);
				LOGGER.info("SMTA Report updated: " + updatedSmtaReport);
			} else {
				SmtaReport newSmtaReport = smtaReportService.create(smtaReport);
				if (newSmtaReport != null && newSmtaReport.getId() != null) {
					LOGGER.info("SMTA Report added: " + newSmtaReport);
				}
			}
		} catch (JsonParseException e) {
			LOGGER.error(e.getMessage());
		} catch (JsonMappingException e) {
			LOGGER.error(e.getMessage());
		} catch (IOException e) {
			LOGGER.error(e.getMessage());
		} catch (Exception e) {
			LOGGER.error(e.getMessage());
		}
	}

	private String toJson(Object obj) {
		ObjectMapper mapper = new ObjectMapper();
		try {
			if (obj != null) {
				String jsonString = mapper.writeValueAsString(obj);
				return jsonString;
			}
		} catch (JsonGenerationException e) {
			LOGGER.error(e.getMessage());
		} catch (JsonMappingException e) {
			LOGGER.error(e.getMessage());
		} catch (IOException e) {
			LOGGER.error(e.getMessage());
		}
		return "{}";
	}
	
}
